/** ***********************************************************************************
* @file         mcu_data_format.c
* @brief        定义MCU数据传输协议的结构体描述
* @details      主要是用来定义MCU数据传输格式，以及数据接口
* @author       杨小珛
* @date         2021/01/30
* @copyright    北京高知科技有限公司    
* @version      V1.0
* @attention    无
**************************************************************************************/

#include "mcu_data_format.h"
#include "com_lib.h"
#include "log_task.h"

extern uint32_t mcu_uart_driver_write( uint8_t *pbuf , uint16_t dlen );
extern uint32_t mcu_can_cfg_can_recv_handle( uint8_t *data, uint16_t len, uint16_t sn, uint16_t id, uint32_t timeout );

GaozQueueHandle_t mcu_protocol_queue[MCU_PROTOCOL_RECV_NUM];
GaozMutexHandle_t mcu_protocol_mutex; 

volatile uint16_t mcu_protocol_send_sn;
volatile uint8_t  mcu_protocol_vhe_id[MCU_VHE_ID_SIZE];

static void mcu_protocol_queue_create(void);
static uint32_t mcu_protocol_queue_get( mcu_protocol_recv_queue_e queue_id,mcu_protocol_infor_t *cfg , uint32_t time_out );
static uint32_t mcu_protocol_queue_put( mcu_protocol_recv_queue_e queue_id,mcu_protocol_infor_t *cfg );
static uint32_t mcu_protocol_filter_id( uint16_t id, mcu_protocol_recv_queue_e *queue_id );

/** ****************************************************************************
* @remarks       uint32_t mcu_protocol_flash_open( void )
* @brief         打开MCU 底层数据操作,专门操作FLASH 的接口
* @param[in]     无
* @param[out]    无
* @return        pdPASS 打开成功，pdFAIL打开失败
* @attention     无
*******************************************************************************/
uint32_t mcu_protocol_flash_open( void )
{   
    mcu_protocol_send_sn = 0;
    memset( (uint8_t *)mcu_protocol_vhe_id , 0x00 , MCU_VHE_ID_SIZE );
    mcu_protocol_mutex = gaoz_mutex_create();
    if( mcu_protocol_mutex == 0 )
    {
        while( 1 ); /*创建失败*/
    }
    mcu_protocol_queue_create();

    return pdPASS;
}

/** ****************************************************************************
* @remarks       static void mcu_protocol_queue_create(void)
* @brief         创建MCU 协议处理消息队列
* @param[in]     无
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
static void mcu_protocol_queue_create(void)
{
    uint32_t rqnum = 0;
    /* 模块内部回复消息队列 */
    for( rqnum = 0; rqnum < MCU_PROTOCOL_RECV_NUM; rqnum++ )
    {
        mcu_protocol_queue[rqnum] = gaoz_queue_create( MCU_PROTOCOL_QUEUE_MAX_NUM, sizeof( mcu_protocol_infor_t ) );
        if( mcu_protocol_queue[rqnum] == 0 )
        {
            while( 1 ); /*创建失败*/
        }
    }
}

/** ****************************************************************************
* @remarks       static uint32_t mcu_protocol_queue_get( mcu_protocol_recv_queue_e queue_id,mcu_protocol_infor_t *cfg , uint32_t time_out )
* @brief         获取MCU 协议数据接收消息队列数据
* @param[in]     *cfg 获取的数据地址，time_out阻塞时间
* @param[out]    无
* @return        pdPASS 接收到数据 pdFAIL 未接收到数据
* @attention     必须在任务中运行
*******************************************************************************/
static uint32_t mcu_protocol_queue_get( mcu_protocol_recv_queue_e queue_id, mcu_protocol_infor_t *cfg , uint32_t time_out )
{
    if( gaoz_queue_get( mcu_protocol_queue[queue_id], cfg, time_out )  == 0 ) //等待回应信号量
    {
        return pdPASS;
    }
    else
    {
        return pdFAIL;
    }
    
    return pdFAIL;
}

/** ****************************************************************************
* @remarks       uint32_t mcu_protocol_queue_put( mcu_protocol_recv_queue_e queue_id, mcu_protocol_infor_t *cfg )
* @brief         发送MCU 协议数据接收消息队列数据
* @param[in]     queue_id 消息队列ID，*cfg 发送的数据地址
* @param[out]    无
* @return        pdPASS 成功    pdFAIL 失败
* @attention     必须在任务中运行
*******************************************************************************/
static uint32_t mcu_protocol_queue_put(mcu_protocol_recv_queue_e queue_id, mcu_protocol_infor_t *cfg )
{
    if( gaoz_queue_put( mcu_protocol_queue[queue_id], cfg, MCU_PROTOCOL_QUEUE_SEND_TIME ) == 0 )
    {
        return pdPASS;
    }
    
    return pdFAIL;
}


/** ****************************************************************************
* @remarks       uint32_t mcu_protocol_escape_rx( uint8_t* lpDst, const uint8_t* lpSrc, uint32_t size )
* @brief         协议处理：  转义接收的协议数据
* @param[out]     lpDst:    目标数据指针
* @param[in]     lpSrc:    源数据指针
* @param[in]     size:    源数据长度
* @param[out]    无
* @return        处理后的数据长度
* @attention     无
*******************************************************************************/
static uint32_t mcu_protocol_escape_rx( uint8_t* lpDst, const uint8_t* lpSrc, uint32_t size )
{
    uint32_t len = size;
    uint8_t* p = ( uint8_t* )lpSrc;

    while ( size )
    {
        if (( p[0] != MCU_ESC_CODE ) || (( p[1] != MCU_ESC_CHAR1 ) && ( p[1] != MCU_ESC_CHAR2 ) ) )
        {
            *lpDst++ = *p++;
            size--;
            continue;
        }

        if ( p[1] == MCU_ESC_CHAR1 )
        {
            *lpDst = MCU_ESC_FLAG1;
        }
        else if ( p[1] == MCU_ESC_CHAR2 )
        {
            *lpDst = MCU_ESC_FLAG2;
        }

        p += 2;
        size -= 2;
        lpDst++;
        len--;
    }
    // Add the end of string flag
    *lpDst = '\0';

    return len;
}

/** ****************************************************************************
* @remarks       uint32_t mcu_protocol_escape_tx( uint8_t* lpDst, const uint8_t* lpSrc, uint32_t size )
* @brief         协议处理：  转义发送数据
* @param[out]     lpDst:    目标数据指针
* @param[in]     lpSrc:    源数据指针
* @param[in]     size:    源数据长度
* @param[out]    无
* @return        处理后的数据长度
* @attention     无
*******************************************************************************/
uint32_t mcu_protocol_escape_tx( uint8_t* lpDst, const uint8_t* lpSrc, uint32_t size )
{
    uint32_t len = size;

    *lpDst++ = MCU_PROTOCOL_HEAD;
	
    while ( size-- )
    {
        if (( *lpSrc != MCU_ESC_FLAG1 ) && ( *lpSrc != MCU_ESC_FLAG2 ) )
        {
            *lpDst++ = *lpSrc++;
            continue;
        }

        *lpDst++ = MCU_ESC_CODE;

        if ( *lpSrc == MCU_ESC_FLAG1 )
        {
            *lpDst = MCU_ESC_CHAR1;
        }
        else if ( *lpSrc == MCU_ESC_FLAG2 )
        {
            *lpDst = MCU_ESC_CHAR2;
        }

        len++;
        lpSrc++;
        lpDst++;
    }

    *lpDst = MCU_PROTOCOL_TAIL;
    len += 2;
    return len;
}

/** ****************************************************************************
* @remarks       uint32_t jt_protocol_parse_rx( void *pv, uint32_t size )
* @brief         协议处理：  转义发送数据
* @param[in]     pv:     源数据指针
* @param[in]     size:   源数据长度
* @param[out]    无
* @return        pdPASS成功/pdFAIL失败
* @attention     无
*******************************************************************************/
uint32_t mcu_protocol_parse_rx( void *pv, uint32_t size )
{   
    mcu_protocol_msg_t *mpmsg = NULL;
    mcu_general_response_t *rsq_msg = NULL;
    mcu_port_wr_int_ack_infor_t *port_wr_int = NULL;
    mcu_protocol_infor_t mcu_infor = { 0 };
    uint8_t *p1 = NULL, *p2 = NULL ,*mp = NULL,*mdata = NULL ,*mspace = NULL;
    uint32_t data_len = 0, pk_tot = 0, pk_idx = 0;
    uint8_t bTmp = 0;
    uint32_t ret = pdFAIL;
    mcu_protocol_recv_queue_e recv_queue = CPU_SPI_INIT_QUEUE_ID;
        
    p2 = ( uint8_t* )pv;
    
    while(( size >= MCU_HEAD_SIZE ) && ( size < MCU_PROTOCOL_MSG_MAX_LEN ) )
    {
        /* fing data head and tail flag. */
        if ( *p2 == MCU_PROTOCOL_HEAD )
        {
            p1 = p2 + 1;
            size--;
        }
        else
        {
            /* 从buf所指内存区域的前count个字节查找字符ch */
            if ( NULL == ( p1 = memchr(( const char* )p2, MCU_PROTOCOL_HEAD, size ) ) )
            {
                return pdFAIL;
            }
            p1++;
            size -= p1 - p2;
        }
        if ( NULL == ( p2 = memchr(( const char* )p1, MCU_PROTOCOL_TAIL, size ) ) )
        {
            return pdFAIL;
        }
        /* If there are multiple data packages, move data pointer to the next package. */
        data_len = p2 - p1;
        size -= ( data_len + 1 );
        p2++;
        mp = gaoz_malloc_mem( MCU_PROTOCOL_MSG_MAX_LEN   );
        if( mp == NULL )
        {
            return pdFAIL;
        }
        /* unescape data package. */
        data_len = mcu_protocol_escape_rx( mp, p1, data_len );
        /** ignore the head and tail flag. */
        if( data_len < MCU_HEAD_SIZE )
        {
            gaoz_free_mem(( void * )mp );
            return pdFAIL;
        }
        p1 = mp;
        /* remove checksum bytes, and check the checksum. */
        data_len--;
        bTmp = check_calc_xor(( const char* )p1, data_len );
	    
        if ( bTmp != p1[data_len] )
        {
            gaoz_free_mem(( void * )mp );
            return pdFAIL;
        }
        p1[data_len] = '\0';
        /* Parse the protocol. */
        mpmsg = ( mcu_protocol_msg_t *)p1;
        mpmsg->id = REV_U16( mpmsg->id );           //消息ID
        mpmsg->attr = REV_U16( mpmsg->attr );       //消息体属性
        memcpy( (uint8_t *)mcu_protocol_vhe_id , (uint8_t *)mpmsg->veh_id , MCU_VHE_ID_SIZE );
        mpmsg->sn = REV_U16( mpmsg->sn );           //消息流水号
        if ( mpmsg->pk_flag )
        {
            /* 当前分包,读取总包数与当前包 */
            pk_tot = mpmsg->pk_total;		        //消息总包数
            pk_idx = mpmsg->pk_idx;                 //消息包序号
        }
        else
        {
            pk_tot = 1;
            pk_idx = 1;
        }
        if(( pk_tot == 1 ) && ( pk_idx == 1 ))
        {
            /*只包含一个数据包*/
            mdata = mpmsg->data;
        }
        else
        {
            mdata = mpmsg->pk_data;
        }
        /* Process all valid messages from server center. */
        switch ( mpmsg->id  )
        {
            case MCU_COMMON_RSP:          /*通用应答*/
                rsq_msg = ( mcu_general_response_t * )mdata;
                rsq_msg->sn = REV_U16( rsq_msg->sn );
                rsq_msg->id = REV_U16( rsq_msg->id );
                if( mcu_protocol_filter_id( rsq_msg->id, &recv_queue ) == pdPASS )
                {
                    mcu_infor.data = NULL;
                    mcu_infor.type = rsq_msg->id;
                    mcu_infor.valid = rsq_msg->res;
                    mcu_infor.attr = 0;
                    mcu_protocol_queue_put( recv_queue,   &mcu_infor );
                    ret = pdPASS;
                }
            break;
            case MCU_READ_FLASH_RSQ:        /*FLASH读数据应答*/
                
            break;
            case MCU_SEND_CAN_DATA:         /*MCU 发送CAN 接收数据*/
                mspace = gaoz_malloc_mem( mpmsg->alen + 8  );
                if( mspace != NULL )
                {
                    memset( (uint8_t *)mspace , 0x00 , mpmsg->alen );
                    memcpy((uint8_t *)mspace ,(uint8_t *)mdata  , mpmsg->alen );
                    if( mcu_can_cfg_can_recv_handle( (uint8_t *)mspace, mpmsg->alen,mpmsg->sn,MCU_SEND_CAN_DATA,  0 ) != pdPASS )
                    {   
                        gaoz_free_mem(( void * )mspace );
                    }
                }
                ret = pdPASS;
            break;
            case MCU_WR_INT_PORT_REQ:           /*MCU 读写、外部触发中断信号*/   
                port_wr_int = ( mcu_port_wr_int_ack_infor_t * )mdata;
                port_wr_int->port = REV_U16( port_wr_int->port );
                port_wr_int->data = REV_U16( port_wr_int->data );
                if( port_wr_int->st == 0x03 )   /*外部中断*/
                {
                    
                }
                else                            /*其他状态*/
                {
                    mcu_infor.data = NULL;
                    mcu_infor.type = mpmsg->id;
                    mcu_infor.valid = 0;
                    mcu_infor.attr = port_wr_int->data ;
                    mcu_protocol_queue_put( CPU_WR_PORT_QUEUE_ID, &mcu_infor );
                }
                ret = pdPASS;
            break;  
            case MCU_SEND_CAN_ST:           /*MCU 发送CAN 状态数据*/
                
            break;
            case MCU_SEND_UART_DATA_REQ:    /*MCU 发送UART 数据*/
                mspace = gaoz_malloc_mem( mpmsg->alen + 8  );
                if( mspace != NULL )
                {
                    memset( (uint8_t *)mspace , 0x00 , mpmsg->alen );
                    memcpy((uint8_t *)mspace ,(uint8_t *)mdata  , mpmsg->alen );
                    if( mcu_can_cfg_can_recv_handle( (uint8_t *)mspace, mpmsg->alen,mpmsg->sn,MCU_SEND_UART_DATA_REQ,  0 ) != pdPASS )
                    {   
                        gaoz_free_mem(( void * )mspace );
                    }
                }
                ret = pdPASS;
            break;
            case MCU_DRIVE_INIT_REQ:             /*MCU 驱动初始化*/
                mspace = gaoz_malloc_mem( mpmsg->alen + 8  );
                if( mspace != NULL )
                {
                    memset( (uint8_t *)mspace , 0x00 , mpmsg->alen );
                    memcpy((uint8_t *)mspace ,(uint8_t *)mdata  , mpmsg->alen );
                    if( mcu_can_cfg_can_recv_handle( (uint8_t *)mspace, mpmsg->alen,mpmsg->sn,MCU_DRIVE_INIT_REQ,  0 ) != pdPASS )
                    {   
                        gaoz_free_mem(( void * )mspace );
                    }
                }
                ret = pdPASS;
            break;
            case MCU_VER_QUERY_RSQ:
                mspace = gaoz_malloc_mem( mpmsg->alen + 8  );
                if( mspace != NULL )
                {   
                    memset( (uint8_t *)mspace , 0x00 , mpmsg->alen );
                    memcpy((uint8_t *)mspace ,(uint8_t *)mdata  , mpmsg->alen );
                    mcu_infor.data = mspace;
                    mcu_infor.type = mpmsg->id;
                    mcu_infor.valid = 0x00;
                    mcu_infor.attr = mpmsg->alen;
                    mcu_protocol_queue_put( CPU_VER_QUERY_QUEUE_ID,   &mcu_infor );
                }
                ret = pdPASS;
            break;
            default:
                ret = pdFAIL;
            break;
        }
        gaoz_free_mem(( void * )mp );
    }
    return ret;
}

/** ****************************************************************************
* @remarks       uint32_t mcu_protocol_filter_id( uint16_t id, mcu_protocol_recv_queue_e *queue_id )
* @brief         过滤MCU 通用应答 ID
* @param[in]     id 通用应答ID数据
* @param[out]    *queue_id 输出消息队列ID
* @return        pdPASS成功/pdFAIL失败
* @attention     无
*******************************************************************************/
static uint32_t mcu_protocol_filter_id( uint16_t id, mcu_protocol_recv_queue_e *queue_id )
{
    uint32_t ret = pdFAIL;
    
    switch( id )
    {
        /*****************SPI FLASH**********************/
        case CPU_SPI_INIT: 
            *queue_id = CPU_SPI_INIT_QUEUE_ID;
            ret = pdPASS;
        break;
        case CPU_ERASE_FLASH: 
            *queue_id = CPU_ERASE_FLASH_QUEUE_ID;
            ret = pdPASS;
        break;
        case CPU_READ_FLASH: 
            *queue_id = CPU_READ_FLASH_QUEUE_ID;
            ret = pdPASS;
        break;
        case CPU_WRITE_FLASH: 
            *queue_id = CPU_WRITE_FLASH_QUEUE_ID;
            ret = pdPASS;
        break;
        /*****************PORT DEV**********************/   
        case CPU_CFG_PORT:
            *queue_id = CPU_CFG_PORT_QUEUE_ID;
            ret = pdPASS;
        break;
        case CPU_WR_PORT:
            *queue_id = CPU_WR_PORT_QUEUE_ID;
            ret = pdPASS;
        break;
        /*****************CAN DEV**********************/   
        case CPU_CAN_INIT:
            *queue_id = CPU_CAN_INIT_QUEUE_ID;
            ret = pdPASS;
        break;
        case CPU_CFG_CAN_ID:
            *queue_id = CPU_CFG_CAN_ID_QUEUE_ID;
            ret = pdPASS;
        break;
        case CPU_SEND_CAN_DATA: 
            *queue_id = CPU_SEND_CAN_DATA_QUEUE_ID;
            ret = pdPASS;
        break;
        case CPU_CAN_CLOSE:
            *queue_id = CPU_CAN_CLOSE_QUEUE_ID;
            ret = pdPASS;
        break;
        /*****************UART DEV**********************/   
        case CPU_UART_OPEN:
            *queue_id = CPU_UART_OPEN_QUEUE_ID;
            ret = pdPASS;
        break;
        case CPU_UART_CLOSE:
            *queue_id = CPU_UART_CLOSE_QUEUE_ID;
            ret = pdPASS;
        break;
        /*****************RUN ST**********************/   
        case CPU_RUN_STATE:
            *queue_id = CPU_RUN_STATE_QUEUE_ID;
            ret = pdPASS;
        break;
        default:
            ret = pdFAIL;
        break;    
    }
    
    return ret;
}

/** ****************************************************************************
* @remarks       uint32_t mcu_protocol_commad_parse( uint8_t *pdata, uint32_t size )
* @brief         命令处理
* @param[in]     *pdata:   数据指针
* @param[in]     size:       数据大小
* @param[out]    无
* @return        pdPASS成功/pdFAIL失败
* @attention     无
*******************************************************************************/
uint32_t mcu_protocol_commad_parse( uint8_t *pdata, uint32_t size )
{
    uint32_t ret = pdFAIL;
    
    if(( size <= 0 ) && ( pdata == NULL ) )
    {
        return ret;
    }
    
    ret = mcu_protocol_parse_rx( pdata, size );
    
    return  ret;
}

/** ****************************************************************************
* @remarks       uint32_t mcu_protocol_pack_send( mcu_protocol_msg_t *pmsg  )
* @brief         协议处理：数据打包发送
* @param[in]     pMsg:   消息结构指针
* @param[out]    无
* @return        pdPASS成功/pdFAIL失败
* @attention     无
*******************************************************************************/
uint32_t mcu_protocol_pack_send( mcu_protocol_msg_t *pmsg )
{
    uint32_t len = 0 , ret = pdFAIL;
    uint8_t bTmp = 0;
    uint8_t *pbuf = NULL;
    
    if( mcu_protocol_mutex != 0 )
    {
        gaoz_mutex_lock( mcu_protocol_mutex );
    }    
    len = pmsg->alen + MCU_HEAD_SIZE;
    if( pmsg->pk_flag == 1 )
    {
        len += 4;
    }
    memset( (uint8_t *)pmsg->veh_id , 0x00 , MCU_VHE_ID_SIZE );
    pmsg->id = REV_U16( pmsg->id );
    pmsg->attr = REV_U16( pmsg->attr );
    memcpy( (uint8_t *)pmsg->veh_id , (uint8_t *)mcu_protocol_vhe_id , MCU_VHE_ID_SIZE );
    pmsg->sn = REV_U16( mcu_protocol_send_sn++ );
    bTmp = check_calc_xor(( const char* )pmsg, len );
    (( uint8_t* )pmsg )[len] = bTmp;
    len++;
    pbuf = gaoz_malloc_mem( len * 2 + 8 );
    if( pbuf != NULL )
    {
        len = mcu_protocol_escape_tx(( uint8_t* )pbuf, ( uint8_t* )pmsg, len );
        ret = mcu_uart_driver_write( (uint8_t *)pbuf , len );
    }
    gaoz_free_mem(( void * )pbuf );
    if( mcu_protocol_mutex != 0)
    {
        gaoz_mutex_unlock( mcu_protocol_mutex );
    }
    
    return ret;
}

/** ****************************************************************************
* @remarks       uint32_t mcu_protocol_general_response_send(uint16_t sn, uint16_t id,  uint8_t res )
* @brief         通用应答发送
* @param[in]     sn 流水号 ，id 发送ID ，res结果
* @param[out]    无
* @return        pdPASS成功/pdFAIL失败
* @attention     无
*******************************************************************************/
uint32_t mcu_protocol_general_response_send( uint16_t sn, uint16_t id,  uint8_t res )
{
    uint32_t ret = pdFAIL;
    uint8_t *mp = NULL;
    mcu_protocol_msg_t *pmsg = NULL;
    mcu_general_response_t *com_send = NULL;
    
    mp = (uint8_t *)gaoz_malloc_mem( MCU_PROTOCOL_MSG_MAX_LEN  );
    if( mp == NULL )
    {
        return pdFAIL;
    }
    memset( (uint8_t *)mp , 0x00 , MCU_PROTOCOL_MSG_MAX_LEN );
    pmsg = ( mcu_protocol_msg_t* )mp;
    pmsg->id = CPU_COMMON_RSP;
    pmsg->attr = 0;
    /*添加数据*/
    com_send = ( mcu_general_response_t * )pmsg->data;
    com_send->sn = REV_U16( sn );
    com_send->id = REV_U16( id );
    com_send->res = res;
    /*计算数据长度*/
    pmsg->alen = sizeof( mcu_general_response_t );
    /*****************************连续发送数据************************************/
    if( mcu_protocol_pack_send( pmsg ) == pdPASS )
    {
        ret = pdPASS;
    }
    gaoz_free_mem((void *)mp);
    
    return ret;
}

/** ****************************************************************************
* @remarks       uint32_t mcu_protocol_heartbear_response_send( void )
* @brief         CPU 心跳应答
* @param[in]     *data 数据源地址， len 数据长度
* @param[out]    无
* @return        pdPASS成功/pdFAIL失败
* @attention     无
*******************************************************************************/
uint32_t mcu_protocol_heartbear_response_send( uint8_t *data, uint16_t len )
{
    uint32_t ret = pdFAIL;
    uint8_t *mp = NULL;
    mcu_protocol_msg_t *pmsg = NULL;

    if(( data == NULL ) || ( len == 0 ) || ( len > MCU_PK_SIZE ))
    {
        return pdFAIL;
    }
    mp = (uint8_t *)gaoz_malloc_mem( MCU_PROTOCOL_MSG_MAX_LEN  );
    if( mp == NULL )
    {
        return pdFAIL;
    }
    memset( (uint8_t *)mp , 0x00 , MCU_PROTOCOL_MSG_MAX_LEN );
    pmsg = ( mcu_protocol_msg_t* )mp;
    pmsg->id = CPU_HEART;
    pmsg->attr = 0;
    /*添加数据*/
    memcpy((uint8_t *)pmsg->data, (const uint8_t *)data, len );
    /*计算数据长度*/
    pmsg->alen = len;
    /*****************************连续发送数据************************************/
    if( mcu_protocol_pack_send( pmsg ) == pdPASS )
    {
        ret = pdPASS;
    }
    gaoz_free_mem((void *)mp);
    
    return ret;
}

/** ****************************************************************************
* @remarks       uint32_t mcu_protocol_dev_init( mcu_protocol_dev_status_e dev_st )
* @brief         MCU 底层驱动初始化
* @param[in]     dev_st 驱动初始化类型
* @param[out]    无
* @return        pdPASS成功/pdFAIL失败
* @attention     无
*******************************************************************************/
uint32_t mcu_protocol_dev_init( mcu_protocol_dev_status_e dev_st )
{
    uint32_t ret = pdFAIL;
    
    if( dev_st == CAN_INIT_DEV )
    {
        ret = mcu_protocol_can_dev_init();
    }
    else if( dev_st == RS232_INIT_DEV )
    {
        ret = mcu_protocol_rs232_dev_init();
    }
    else if( dev_st == PORT_INIT_DEV )
    {
        ret = mcu_protocol_port_dev_init();
    }
    else
    {
        ret = pdFAIL;
    }
    
    return ret;
}

/** ****************************************************************************
* @remarks       uint32_t mcu_protocol_can_dev_init( void )
* @brief         MCU CAN 底层驱动初始化
* @param[in]     无
* @param[out]    无
* @return        pdPASS成功/pdFAIL失败
* @attention     无
*******************************************************************************/
uint32_t mcu_protocol_can_dev_init( void )
{
    uint32_t ret = pdFAIL , size = 0 , i = 0;
    uint8_t *mp = NULL;
    mcu_protocol_msg_t *pmsg = NULL;
    can_dev_infor_t can_dev[2] = { 0 };
    mcu_protocol_infor_t mcu_infor = { 0 };
    
    mp = (uint8_t *)gaoz_malloc_mem( MCU_PROTOCOL_MSG_MAX_LEN  );
    if( mp == NULL )
    {
        return pdFAIL;
    }
    size = can_config_dev_infor_get( CAN_DEV , (uint8_t *)can_dev );
    size = size / sizeof( can_dev_infor_t );
    if( size > SYS_CONFIG_CAN_MAX_NUM )
    {
        gaoz_free_mem((void *)mp);
        return pdFAIL;
    }
    if( size == 0 )
    {
        gaoz_free_mem((void *)mp);
        return pdPASS;
    }
    for( i = 0 ; i < size ; i ++ )
    {
        memset( (uint8_t *)mp , 0x00 , MCU_PROTOCOL_MSG_MAX_LEN );
        pmsg = ( mcu_protocol_msg_t* )mp;
        pmsg->id = CPU_CAN_INIT;
        pmsg->attr = 0;
        /*添加数据*/
        memcpy((uint8_t *)pmsg->data, (uint8_t *)&can_dev[i],sizeof( can_dev_infor_t ));
        /*计算数据长度*/
        pmsg->alen = sizeof( can_dev_infor_t );
        /*****************************连续发送数据************************************/
        if( mcu_protocol_pack_send( pmsg ) == pdPASS )
        {
            if( mcu_protocol_queue_get(CPU_CAN_INIT_QUEUE_ID, &mcu_infor, MCU_PROTOCOL_QUEUE_WAIT_TIME ) == pdPASS )
            {
                if(( mcu_infor.type == CPU_CAN_INIT ) && ( mcu_infor.valid ==  0 ))
                {   
                    ret = pdPASS;
                }
            }
            else
            {
                ret = pdFAIL;
                break;
            }
        }
    }
    gaoz_free_mem((void *)mp);
    
    return ret;
}

/** ****************************************************************************
* @remarks       uint32_t mcu_protocol_rs232_dev_init( void )
* @brief         MCU RS232底层驱动初始化
* @param[in]     无
* @param[out]    无
* @return        pdPASS成功/pdFAIL失败
* @attention     无
*******************************************************************************/
uint32_t mcu_protocol_rs232_dev_init( void )
{
    uint32_t ret = pdFAIL , size = 0, i = 0;
    uint8_t *mp = NULL;
    mcu_protocol_msg_t *pmsg = NULL;
    rs232_dev_infor_t rs232_dev[2] = { 0 };
    mcu_protocol_infor_t mcu_infor = { 0 };
    
    mp = (uint8_t *)gaoz_malloc_mem( MCU_PROTOCOL_MSG_MAX_LEN  );
    if( mp == NULL )
    {
        return pdFAIL;
    }
    size = can_config_dev_infor_get( RS232_DEV , (uint8_t *)rs232_dev );
    size = size / sizeof( rs232_dev_infor_t );
    if( size > SYS_CONFIG_RS232_MAX_NUM )
    {
        gaoz_free_mem((void *)mp);
        return pdFAIL;
    }
    if( size == 0 )
    {
        gaoz_free_mem((void *)mp);
        return pdPASS;
    }
    for( i = 0 ; i < size ; i ++ )
    {
        memset( (uint8_t *)mp , 0x00 , MCU_PROTOCOL_MSG_MAX_LEN );
        pmsg = ( mcu_protocol_msg_t* )mp;
        pmsg->id = CPU_UART_OPEN;
        pmsg->attr = 0;
        /*添加数据*/
        memcpy((uint8_t *)pmsg->data, (uint8_t *)&rs232_dev[i],sizeof( rs232_dev_infor_t ));
        /*计算数据长度*/
        pmsg->alen = sizeof( rs232_dev_infor_t );
        /*****************************连续发送数据************************************/
        if( mcu_protocol_pack_send( pmsg ) == pdPASS )
        {
            if( mcu_protocol_queue_get(CPU_UART_OPEN_QUEUE_ID, &mcu_infor, MCU_PROTOCOL_QUEUE_WAIT_TIME ) == pdPASS )
            {
                if(( mcu_infor.type == CPU_UART_OPEN ) && ( mcu_infor.valid ==  0 ))
                {
                    ret = pdPASS;
                }
            }
            else
            {
                ret = pdFAIL;
                break;
            }
        }
    }
    gaoz_free_mem((void *)mp);
    
    return ret;
}

/** ****************************************************************************
* @remarks       uint32_t mcu_protocol_port_dev_init( void )
* @brief         MCU PORT底层驱动初始化
* @param[in]     无
* @param[out]    无
* @return        pdPASS成功/pdFAIL失败
* @attention     无
*******************************************************************************/
uint32_t mcu_protocol_port_dev_init( void )
{
    uint32_t ret = pdFAIL , size = 0, i = 0;
    uint8_t *mp = NULL;
    mcu_protocol_msg_t *pmsg = NULL;
    uint16_t port_dev[SYS_CONFIG_PORT_MAX_NUM] = { 0 };
    mcu_protocol_infor_t mcu_infor = { 0 };
    
    mp = (uint8_t *)gaoz_malloc_mem( MCU_PROTOCOL_MSG_MAX_LEN  );
    if( mp == NULL )
    {
        return pdFAIL;
    }
    size = can_config_dev_infor_get( PORT_DEV , (uint8_t *)port_dev );
    size = size / sizeof( uint16_t );
    if( size > SYS_CONFIG_PORT_MAX_NUM )
    {
        gaoz_free_mem((void *)mp);
        return pdFAIL;
    }
    if( size == 0 )
    {
        gaoz_free_mem((void *)mp);
        return pdPASS;
    }
    for( i = 0 ; i < size ; i ++ )
    {
        memset( (uint8_t *)mp , 0x00 , MCU_PROTOCOL_MSG_MAX_LEN );
        pmsg = ( mcu_protocol_msg_t* )mp;
        pmsg->id = CPU_CFG_PORT;
        pmsg->attr = 0;
        /*添加数据*/
        pmsg->data[0] = (uint8_t )(( port_dev[i] & 0xFF00 ) >> 8);
        pmsg->data[1] = (uint8_t )( port_dev[i] & 0x00FF );
        /*计算数据长度*/
        pmsg->alen = sizeof( uint16_t );
        /*****************************连续发送数据************************************/
        if( mcu_protocol_pack_send( pmsg ) == pdPASS )
        {
            if( mcu_protocol_queue_get(CPU_CFG_PORT_QUEUE_ID, &mcu_infor, MCU_PROTOCOL_QUEUE_WAIT_TIME ) == pdPASS )
            {
                if(( mcu_infor.type == CPU_CFG_PORT ) && ( mcu_infor.valid ==  0 ))
                {
                    ret = pdPASS;
                }
            }
            else
            {
                ret = pdFAIL;
                break;
            }
        }
    }
    gaoz_free_mem((void *)mp);
    
    return ret;
}

/** ****************************************************************************
* @remarks       uint32_t mcu_protocol_can_id_filtering_init( void )
* @brief         MCU CAN ID 过滤设置
* @param[in]     无
* @param[out]    无
* @return        pdPASS成功/pdFAIL失败
* @attention     无
*******************************************************************************/
uint32_t mcu_protocol_can_id_filtering_init( void )
{
    if( mcu_protocol_can_id_init( CAN1_CHANNEL_NO )   != pdPASS )
    {
        return pdFAIL;
    }
    if( mcu_protocol_can_id_init( CAN2_CHANNEL_NO )   != pdPASS )
    {
        return pdFAIL;
    }
    
    return pdPASS;
}

/** ****************************************************************************
* @remarks       uint32_t mcu_protocol_can_id_init( uint8_t channel )
* @brief         MCU CAN ID 过滤设置
* @param[in]     channel CAN 通道 1,2
* @param[out]    无
* @return        pdPASS成功/pdFAIL失败
* @attention     无
*******************************************************************************/
uint32_t mcu_protocol_can_id_init( uint8_t channel )
{
    uint32_t ret = pdFAIL , size = 0 , i = 0;
    uint8_t *mp = NULL;
    mcu_protocol_msg_t *pmsg = NULL;
    uint32_t can_id[MCU_CAN_ID_NUM] = { 0 };
    mcu_can_id_infor_t *canp = NULL;
    mcu_protocol_infor_t mcu_infor = { 0 };

    mp = (uint8_t *)gaoz_malloc_mem( MCU_PROTOCOL_MSG_MAX_LEN  );
    if( mp == NULL )
    {
        return pdFAIL;
    }
    memset( (uint8_t *)mp , 0x00 , MCU_PROTOCOL_MSG_MAX_LEN );
    pmsg = ( mcu_protocol_msg_t* )mp;
    pmsg->id = CPU_CFG_CAN_ID;
    pmsg->attr = 0;
    /*添加数据*/
    size = can_config_id_infor_get( channel , (uint32_t *)can_id );
    if( size > SYS_CONFIG_UNIT_MAX_NUM )
    {
        gaoz_free_mem((void *)mp);
        return pdFAIL;
    }
    if( size == 0 )
    {
        gaoz_free_mem((void *)mp);
        return pdPASS;
    }
    
    canp = ( mcu_can_id_infor_t * )pmsg->data;
    canp->channel = channel;
    canp->num = size;
    for( i = 0 ; i < size ; i ++ )
    {
        canp->cid[i] = REV_U32(  can_id[i] );
    }
    /*计算数据长度*/
    pmsg->alen = size * sizeof( uint32_t ) + 2;
    /*****************************连续发送数据************************************/
    if( mcu_protocol_pack_send( pmsg ) == pdPASS )
    {
        if( mcu_protocol_queue_get(CPU_CFG_CAN_ID_QUEUE_ID, &mcu_infor, MCU_PROTOCOL_QUEUE_WAIT_TIME ) == pdPASS )
        {
            if(( mcu_infor.type == CPU_CFG_CAN_ID ) && ( mcu_infor.valid ==  0 ))
            {
                ret = pdPASS;
            }
        }
    }
    gaoz_free_mem((void *)mp);
    
    return ret;
}

/** ****************************************************************************
* @remarks       uint32_t mcu_protocol_can_data_send( can_send_infor_t *infor ,uint8_t *exit)
* @brief         MCU 协议组包 发送CAN 数据
* @param[in]     *infor CAN 发送信息，*exit 强制退出状态
* @param[out]    无
* @return        pdPASS成功/pdFAIL失败
* @attention     无
*******************************************************************************/
uint32_t mcu_protocol_can_data_send( can_send_infor_t *infor ,uint8_t *exit )
{
    uint32_t ret = pdFAIL ,count = 0;
    uint8_t *mp = NULL;
    mcu_protocol_msg_t *pmsg = NULL;
    mcu_can_send_infor_t *can_send = NULL;
    mcu_protocol_infor_t mcu_infor = { 0 };
    
    if( infor == NULL )
    {
        return pdFAIL;
    }
    mp = (uint8_t *)gaoz_malloc_mem( MCU_PROTOCOL_MSG_MAX_LEN  );
    if( mp == NULL )
    {
        return pdFAIL;
    }
    if( infor->count == 0 )
    {
        gaoz_free_mem((void *)mp);
        return pdFAIL;
    }
    for( ;; )
    {
        if( *exit != 0 )
        {
            ret = pdFAIL;
            break;
        }
        memset( (uint8_t *)mp , 0x00 , MCU_PROTOCOL_MSG_MAX_LEN );
        pmsg = ( mcu_protocol_msg_t* )mp;
        pmsg->id = CPU_SEND_CAN_DATA;
        pmsg->attr = 0;
        /*添加数据*/
        can_send = ( mcu_can_send_infor_t * )pmsg->data;
        can_send->channel = infor->channel;
        can_send->cid = REV_U32( infor->cid );
        can_send->len = infor->len;
        memcpy((uint8_t *)can_send->data ,(uint8_t *)infor->data  , infor->len );
        /*计算数据长度*/
        pmsg->alen = sizeof( mcu_can_send_infor_t );
        /*****************************连续发送数据************************************/
        if( mcu_protocol_pack_send( pmsg ) == pdPASS )
        {
            if( mcu_protocol_queue_get(CPU_SEND_CAN_DATA_QUEUE_ID, &mcu_infor, MCU_PROTOCOL_QUEUE_WAIT_TIME ) == pdPASS )
            {
                if(( mcu_infor.type == CPU_SEND_CAN_DATA ) && ( mcu_infor.valid ==  0 ))
                {
                    ret = pdPASS;
                }
            }
            else
            {
                ret = pdFAIL;
                break;
            }
        }
        /*进行系统延时，当循环测试不为0，time为0时直接退出*/
        if( infor->count == 0xFF )
        {
            if(( infor->time >= 10 ) && ( infor->time <= 10000 ))
            {
                gaoz_task_sleep( infor->time ); 
            }
            else
            {
                break;
            }
        }
        else if(( infor->count >= 1 ) && ( infor->count <= 200 ))
        {
            if(( infor->time >= 10 ) && ( infor->time <= 10000 ))
            {
                gaoz_task_sleep( infor->time ); 
            }
            else
            {
                break;
            }
            count ++;
            if( count == infor->count )
            {
                break;
            }
        }
        else
        {
            break;
        }
    }
    gaoz_free_mem((void *)mp);
    
    return ret;
}

/** ****************************************************************************
* @remarks       uint32_t mcu_protocol_can_format_recv( uint8_t *data , uint16_t len )
* @brief         MCU CAN 数据包 格式数据接收处理
* @param[in]     *data 数据源地址，len数据长度
* @param[out]    无
* @return        pdPASS成功/pdFAIL失败
* @attention     无
*******************************************************************************/
uint32_t mcu_protocol_can_format_recv( uint8_t *data , uint16_t len )
{
    uint32_t ret = pdFAIL , i = 0 , dlen = 0;
    uint8_t  format_num = 0;
    mcu_can_data_infor_t *can_format = NULL;
    mcu_can_data_infor_t can_data = { 0 };

    if(( data == NULL ) || ( len == 0 ))
    {
        return pdFAIL;
    }
    format_num = data[dlen];
    dlen += 1;
    for( i = 0; i < format_num; i ++ )
    {
        can_format = ( mcu_can_data_infor_t * )&data[dlen];
        can_data.channel = can_format->channel;
        can_data.cid = REV_U32( can_format->cid ); 
        can_data.len = can_format->len;
        memcpy( ( uint8_t *)can_data.data, ( uint8_t *)can_format->data, can_format->len );
        if( pdPASS == can_config_data_infor_set( can_data.channel , can_data.cid ,can_data.len, (uint8_t *)can_data.data ))
        {
            ret = pdPASS;
        }
        dlen += sizeof( mcu_can_data_infor_t );
    }
        
    return ret;
}

/** ****************************************************************************
* @remarks       uint32_t mcu_protocol_port_signal_read( port_input_infor_t *infor , uint16_t *out )
* @brief         读取MCU PORT 数据
* @param[in]     *infor PORT配置信息
* @param[out]    *out 数据输出目标地址
* @return        pdPASS成功/pdFAIL失败
* @attention     无
*******************************************************************************/
uint32_t mcu_protocol_port_signal_read( port_input_infor_t *infor , uint16_t *out )
{
    uint32_t ret = pdFAIL;
    uint8_t *mp = NULL;
    mcu_protocol_msg_t *pmsg = NULL;
    mcu_protocol_infor_t mcu_infor = { 0 };
    mcu_port_cfg_infor_t pcfg;
    
    if(( infor == NULL ) || ( out == NULL ))
    {
        return pdFAIL;
    }
    mp = (uint8_t *)gaoz_malloc_mem( MCU_PROTOCOL_MSG_MAX_LEN  );
    if( mp == NULL )
    {
        return pdFAIL;
    }
    *out = 0;
    memset( (uint8_t *)mp , 0x00 , MCU_PROTOCOL_MSG_MAX_LEN );
    pmsg = ( mcu_protocol_msg_t* )mp;
    pmsg->id = CPU_WR_PORT;
    pmsg->attr = 0;
    /*添加数据*/
    pcfg.pin = infor->pin;
    pcfg.name = infor->name;
    if( infor->st == 0x1 )           /*INPUT*/
    {
        pcfg.st = 0x1;
    }
    else if( infor->st == 0x2 )    /*ADC*/
    {
        pcfg.st = 0x2;
    }
    else if( infor->st == 0x3 )    /*INTERRRUPT*/
    {
        /*获取中断数据*/
        gaoz_free_mem((void *)mp);
        return pdPASS;
    }
    else 
    {
        gaoz_free_mem((void *)mp);
        return pdFAIL;
    }
    pcfg.mode = 0;
    pmsg->data[0] = (uint8_t )(( pcfg.port & 0xFF00 ) >> 8);
    pmsg->data[1] = (uint8_t )( pcfg.port & 0x00FF );
    /*计算数据长度*/
    pmsg->alen = sizeof( uint16_t );
    /*****************************连续发送数据************************************/
    if( mcu_protocol_pack_send( pmsg ) == pdPASS )
    {
        if( mcu_protocol_queue_get( CPU_WR_PORT_QUEUE_ID,&mcu_infor, MCU_PROTOCOL_QUEUE_WAIT_TIME ) == pdPASS )
        {
            if(( mcu_infor.type == MCU_WR_INT_PORT_REQ ) && ( mcu_infor.valid ==  0 ))
            {
                *out = mcu_infor.attr;
                ret = pdPASS;
            }
        }
    }
    gaoz_free_mem((void *)mp);

    return ret;
}

/** ****************************************************************************
* @remarks       uint32_t mcu_protocol_port_signal_write( port_output_infor_t *infor , uint8_t *exit)
* @brief         控制PORT 操作
* @param[in]     *infor PORT 发送信息，*exit 强制退出状态
* @param[out]    无
* @return        pdPASS成功/pdFAIL失败
* @attention     无
*******************************************************************************/
uint32_t mcu_protocol_port_signal_write( port_output_infor_t *infor, uint8_t *exit )
{
    uint32_t ret = pdFAIL,count = 0;
    uint8_t *mp = NULL;
    uint8_t out_cnt = 0;
    mcu_protocol_msg_t *pmsg = NULL;
    mcu_protocol_infor_t mcu_infor = { 0 };
    mcu_port_cfg_infor_t pcfg;
    static uint8_t con_pin = 0;
    
    if( infor == NULL )
    {
        return pdFAIL;
    }
    mp = (uint8_t *)gaoz_malloc_mem( MCU_PROTOCOL_MSG_MAX_LEN  );
    if( mp == NULL )
    {
        return pdFAIL;
    }
    if( infor->count == 0 )
    {
        gaoz_free_mem((void *)mp);
        return pdFAIL;
    }
    for( ;; )
    {
        if( *exit != 0 )
        {
            ret = pdFAIL;
            break;
        }
        memset( (uint8_t *)mp , 0x00 , MCU_PROTOCOL_MSG_MAX_LEN );
        pmsg = ( mcu_protocol_msg_t* )mp;
        pmsg->id = CPU_WR_PORT;
        pmsg->attr = 0;
        /*添加数据*/
        pcfg.pin = infor->pin;
        pcfg.name = infor->name;
        if( infor->st == 0x0 )           /*OUTPUT*/
        {
            pcfg.st = 0x0;
        }
        else 
        {
            ret = pdFAIL;
            break;
        }
        if( infor->out == 0x01 )        //低电平控制
        {
            out_cnt = 0x01;
            pcfg.mode = 0x0;              
        }
        else if( infor->out == 0x02 ) //高电平控制
        {
            out_cnt = 0x01;
            pcfg.mode = 0x1;              
        }
        else if( infor->out == 0x03 )   //脉冲信号
        {
            out_cnt = 0x02;
            if( con_pin == 0 )
            {
                if(( infor->mode == 0x00 ) || ( infor->mode == 0x01 ))
                {
                    pcfg.mode = 0x0;
                }
                else if(( infor->mode == 0x02 ) || ( infor->mode == 0x03 ))
                {
                    pcfg.mode = 0x1;
                }
                con_pin = 1;
            }
            else
            {
                if(( infor->mode == 0x00 ) || ( infor->mode == 0x01 ))
                {
                    pcfg.mode = 0x1;
                }
                else if(( infor->mode == 0x02 ) || ( infor->mode == 0x03 ))
                {
                    pcfg.mode = 0x0;
                }
                pcfg.mode = 0x0; 
                con_pin = 0;
            }
        }
        else
        {
            ret = pdFAIL;
            break;
        }
        pmsg->data[0] = (uint8_t )(( pcfg.port & 0xFF00 ) >> 8);
        pmsg->data[1] = (uint8_t )( pcfg.port & 0x00FF );
        /*计算数据长度*/
        pmsg->alen = sizeof( uint16_t );
        /*****************************连续发送数据************************************/
        if( mcu_protocol_pack_send( pmsg ) == pdPASS )
        {
            if( mcu_protocol_queue_get(CPU_WR_PORT_QUEUE_ID, &mcu_infor, MCU_PROTOCOL_QUEUE_WAIT_TIME ) == pdPASS )
            {
                if(( mcu_infor.type == MCU_WR_INT_PORT_REQ ) && ( mcu_infor.valid ==  0 ))
                {
                    ret = pdPASS;
                }
            }
            else
            {
                ret = pdFAIL;
                break;
            }
        }
        /*进行系统延时，当循环测试不为0，time为0时直接退出*/
        if( infor->count == 0xFF )
        {
            if(( infor->time >= 10 ) && ( infor->time <= 10000 ))
            {
                gaoz_task_sleep( infor->time ); 
            }
            else
            {
                break;
            }
        }
        else if(( infor->count >= 1 ) && ( infor->count <= 200 ))
        {
            if(( infor->time >= 10 ) && ( infor->time <= 10000 ))
            {
                gaoz_task_sleep( infor->time ); 
            }
            else
            {
                break;
            }
            count ++;
            if( count == ( infor->count * out_cnt ) )
            {
                break;
            }
        }
        else
        {
            break;
        }
    }
    con_pin = 0;
    gaoz_free_mem((void *)mp);
    
    return ret;
}

/** ****************************************************************************
* @remarks       uint32_t mcu_protocol_control_run_status( mcu_protocol_control_status_e status )
* @brief         控制MCU 运行的状态
* @param[in]     status  设置运行的状态
* @param[out]    无
* @return        pdPASS成功/pdFAIL失败
* @attention     无
*******************************************************************************/
uint32_t mcu_protocol_control_run_status( mcu_protocol_control_status_e status )
{
    uint32_t ret = pdFAIL;
    uint8_t *mp = NULL;
    mcu_protocol_msg_t *pmsg = NULL;
    mcu_protocol_infor_t mcu_infor = { 0 };

    mp = (uint8_t *)gaoz_malloc_mem( MCU_PROTOCOL_MSG_MAX_LEN  );
    if( mp == NULL )
    {
        return pdFAIL;
    }
    memset( (uint8_t *)mp , 0x00 , MCU_PROTOCOL_MSG_MAX_LEN );
    pmsg = ( mcu_protocol_msg_t* )mp;
    pmsg->id = CPU_RUN_STATE;
    pmsg->attr = 0;
    /*添加数据，控制运行状态*/
    pmsg->data[0] = status;  
    /*计算数据长度*/
    pmsg->alen = 1;
    /*****************************连续发送数据************************************/
    if(( status == CONTROL_RESTART_MCU_ST ) || ( status == CONTROL_RESTART_CPU_ST ) )
    {
        if( mcu_protocol_pack_send( pmsg ) == pdPASS )
        {
            if( mcu_protocol_queue_get(CPU_RUN_STATE_QUEUE_ID, &mcu_infor, MCU_PROTOCOL_QUEUE_WAIT_TIME ) == pdPASS )
            {
                if(( mcu_infor.type == CPU_RUN_STATE ) && ( mcu_infor.valid ==  0 ))
                {
                    ret = pdPASS;
                }
            }
            else
            {
                ret = pdFAIL;
            }
        }
    }
    else
    {
        ret = mcu_protocol_pack_send( pmsg );
    }
    gaoz_free_mem((void *)mp);
    
    return ret;
}

/** ****************************************************************************
* @remarks       uint32_t mcu_protocol_mcu_version_get( uint8_t *version, uint32_t *len )
* @brief         获取MCU系统版本号
* @param[in]     无
* @param[out]    *version 版本号目标地址， *len 版本号长度
* @return        pdPASS成功/pdFAIL失败
* @attention     无
*******************************************************************************/
uint32_t mcu_protocol_mcu_version_get( uint8_t *version, uint32_t *len )
{
    uint32_t ret = pdFAIL;
    uint8_t *mp = NULL;
    mcu_protocol_msg_t *pmsg = NULL;
    mcu_protocol_infor_t mcu_infor = { 0 };

    if(( version == NULL ) || ( len == NULL ))
    {
        return pdFAIL;
    }
    mp = (uint8_t *)gaoz_malloc_mem( MCU_PROTOCOL_MSG_MAX_LEN  );
    if( mp == NULL )
    {
        return pdFAIL;
    }
    memset( (uint8_t *)mp , 0x00 , MCU_PROTOCOL_MSG_MAX_LEN );
    pmsg = ( mcu_protocol_msg_t* )mp;
    pmsg->id = CPU_VER_QUERY;
    pmsg->attr = 0;
    /*消息体为空*/
    pmsg->alen = 0;
    /*****************************连续发送数据************************************/
    if( mcu_protocol_pack_send( pmsg ) == pdPASS )
    {
        if( mcu_protocol_queue_get(CPU_VER_QUERY_QUEUE_ID, &mcu_infor, MCU_PROTOCOL_QUEUE_WAIT_TIME ) == pdPASS )
        {
            if(( mcu_infor.type == MCU_VER_QUERY_RSQ ) && ( mcu_infor.valid ==  0 ))
            {
                memcpy((uint8_t *)version, (const uint8_t *)mcu_infor.data, mcu_infor.attr );
                *len = mcu_infor.attr;
                ret = pdPASS;
            }
            if( mcu_infor.data != NULL )
            {
                gaoz_free_mem((void *)mcu_infor.data);
            }
        }
        else
        {
            ret = pdFAIL;
        }
    }
    gaoz_free_mem((void *)mp);
    
    return ret;
}

/** ****************************************************************************
* @remarks       uint32_t mcu_protocol_mcu_port_cfg( mcu_port_cfg_infor_t  port_cfg )
* @brief         初始化MCU PORT
* @param[in]     port_cfg 引脚配置
* @param[out]    无
* @return        pdPASS成功/pdFAIL失败
* @attention     无
*******************************************************************************/
uint32_t mcu_protocol_mcu_port_cfg( mcu_port_cfg_infor_t  port_cfg )
{
    uint32_t ret = pdFAIL;
    uint8_t *mp = NULL;
    mcu_protocol_msg_t *pmsg = NULL;
    mcu_protocol_infor_t mcu_infor = { 0 };
    
    mp = (uint8_t *)gaoz_malloc_mem( MCU_PROTOCOL_MSG_MAX_LEN  );
    if( mp == NULL )
    {
        return pdFAIL;
    }
    memset( (uint8_t *)mp , 0x00 , MCU_PROTOCOL_MSG_MAX_LEN );
    pmsg = ( mcu_protocol_msg_t* )mp;
    pmsg->id = CPU_CFG_PORT;
    pmsg->attr = 0;
    /*添加数据*/
    pmsg->data[0] = (uint8_t )(( port_cfg.port & 0xFF00 ) >> 8);
    pmsg->data[1] = (uint8_t )( port_cfg.port & 0x00FF );
    /*计算数据长度*/
    pmsg->alen = sizeof( uint16_t );
    /*****************************连续发送数据************************************/
    if( mcu_protocol_pack_send( pmsg ) == pdPASS )
    {
        if( mcu_protocol_queue_get(CPU_CFG_PORT_QUEUE_ID, &mcu_infor, MCU_PROTOCOL_QUEUE_WAIT_TIME ) == pdPASS )
        {
            if(( mcu_infor.type == CPU_CFG_PORT ) && ( mcu_infor.valid ==  0 ))
            {
                ret = pdPASS;
            }
        }
        else
        {
            ret = pdFAIL;
        }
    }
    gaoz_free_mem((void *)mp);
    
    return ret;
}

/** ****************************************************************************
* @remarks       uint32_t mcu_protocol_mcu_port_read_write( port_input_infor_t *infor , uint16_t *out )
* @brief         读写MCU PORT 数据
* @param[in]     *infor PORT配置信息
* @param[out]    *out 数据输出目标地址
* @return        pdPASS成功/pdFAIL失败
* @attention     无
*******************************************************************************/
uint32_t mcu_protocol_mcu_port_read_write( mcu_port_cfg_infor_t  port_cfg , uint16_t *out )
{
    uint32_t ret = pdFAIL;
    uint8_t *mp = NULL;
    mcu_protocol_msg_t *pmsg = NULL;
    mcu_protocol_infor_t mcu_infor = { 0 };

    if( out == NULL )
    {
        return pdFAIL;
    }
    mp = (uint8_t *)gaoz_malloc_mem( MCU_PROTOCOL_MSG_MAX_LEN  );
    if( mp == NULL )
    {
        return pdFAIL;
    }
    *out = 0;
    memset( (uint8_t *)mp , 0x00 , MCU_PROTOCOL_MSG_MAX_LEN );
    pmsg = ( mcu_protocol_msg_t* )mp;
    pmsg->id = CPU_WR_PORT;
    pmsg->attr = 0;
    /*添加数据*/
    pmsg->data[0] = (uint8_t )(( port_cfg.port & 0xFF00 ) >> 8);
    pmsg->data[1] = (uint8_t )( port_cfg.port & 0x00FF );
    /*计算数据长度*/
    pmsg->alen = sizeof( uint16_t );
    /*****************************连续发送数据************************************/
    if( mcu_protocol_pack_send( pmsg ) == pdPASS )
    {
        if( mcu_protocol_queue_get( CPU_WR_PORT_QUEUE_ID,&mcu_infor, MCU_PROTOCOL_QUEUE_WAIT_TIME ) == pdPASS )
        {
            if(( mcu_infor.type == MCU_WR_INT_PORT_REQ ) && ( mcu_infor.valid ==  0 ))
            {
                *out = mcu_infor.attr;
                ret = pdPASS;
            }
        }
    }
    gaoz_free_mem((void *)mp);
    
    return ret;
}





